#include "utils/logger.h"
#include <cstdarg>
#include <cstdio>
#include <ctime>

// 初始化静态成员变量
LogLevel Logger::current_level_ = LogLevel::INFO;
std::mutex Logger::log_mutex_;

// 设置日志级别
void Logger::set_level(LogLevel level)
{
    std::lock_guard<std::mutex> lock(log_mutex_);
    current_level_ = level;
}

// 获取当前日志级别
LogLevel Logger::get_level()
{
    std::lock_guard<std::mutex> lock(log_mutex_);
    return current_level_;
}

// 记录调试信息
void Logger::debug(const std::string &message)
{
    if (current_level_ <= LogLevel::DEBUG)
    {
        log_message(LogLevel::DEBUG, message);
    }
}

// 记录一般信息
void Logger::info(const std::string &message)
{
    if (current_level_ <= LogLevel::INFO)
    {
        log_message(LogLevel::INFO, message);
    }
}

// 记录警告信息
void Logger::warning(const std::string &message)
{
    if (current_level_ <= LogLevel::WARNING)
    {
        log_message(LogLevel::WARNING, message);
    }
}

// 记录错误信息
void Logger::error(const std::string &message)
{
    if (current_level_ <= LogLevel::ERROR)
    {
        log_message(LogLevel::ERROR, message);
    }
}

// 格式化日志消息
void Logger::log(LogLevel level, const char *format, ...)
{
    if (level < current_level_)
    {
        return; // 低于当前日志级别，不记录
    }

    // 使用可变参数处理格式化字符串
    char buffer[1024];
    va_list args;
    va_start(args, format);
    vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);

    log_message(level, std::string(buffer));
}

// 实际执行日志记录的核心方法
void Logger::log_message(LogLevel level, const std::string &message)
{
    std::lock_guard<std::mutex> lock(log_mutex_);

    // 获取当前时间
    std::string time_str = get_current_time();

    // 获取级别字符串
    std::string level_str = level_to_string(level);

    // 输出到标准输出
    std::cout << "[" << time_str << "] "
              << "[" << level_str << "] "
              << message << std::endl;
}

// 获取当前时间字符串
std::string Logger::get_current_time()
{
    auto now = std::chrono::system_clock::now();
    auto time = std::chrono::system_clock::to_time_t(now);
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
                  now.time_since_epoch()) %
              1000;

    std::tm tm_info;
#ifdef _WIN32
    localtime_s(&tm_info, &time); // windows才能用
#else
    localtime_r(&time, &tm_info); // linux才能用
#endif
    // localtime_r(&time, &tm_info); // 线程安全版本

    std::stringstream ss;
    ss << std::put_time(&tm_info, "%Y-%m-%d %H:%M:%S")
       << "." << std::setfill('0') << std::setw(3) << ms.count();

    return ss.str();
}

// 将日志级别转换为字符串
std::string Logger::level_to_string(LogLevel level)
{
    switch (level)
    {
    case LogLevel::DEBUG:
        return "DEBUG";
    case LogLevel::INFO:
        return "INFO";
    case LogLevel::WARNING:
        return "WARNING";
    case LogLevel::ERROR:
        return "ERROR";
    default:
        return "UNKNOWN";
    }
}